﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

namespace Walson.Form.Common
{
    [DefaultEvent("StateChanged")]
    public partial class LightText : Control
    {
        public new string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
                RedrawImage();
            }
        }

        private int _Blur = 5;
        public int Blur
        {
            get
            {
                return _Blur;
            }
            set
            {
                _Blur = value;
                RedrawImage();
            }
        }

        public new Font Font
        {
            get
            {
                return base.Font;
            }
            set
            {
                base.Font = value;
                RedrawImage();
            }
        }

        private Color _LightColor = Color.Red;
        /// <summary>
        /// 点亮时的颜色
        /// </summary>
        public Color LightColor
        {
            get
            {
                return _LightColor;
            }
            set
            {
                _LightColor = value;
                RedrawImage();
            }
        }

        private Color _GlowColor = Color.Red;
        /// <summary>
        /// 辉光颜色
        /// </summary>
        public Color GlowColor
        {
            get
            {
                return _GlowColor;
            }
            set
            {
                _GlowColor = value;
                RedrawImage();
            }
        }

        private Color _DarkColor = Color.Maroon;
        /// <summary>
        /// 未点亮时的颜色
        /// </summary>
        public Color DarkColor
        {
            get
            {
                return _DarkColor;
            }
            set
            {
                _DarkColor = value;
                RedrawImage();
            }
        }

        private int _Alpha = 20;
        public int Alpha
        {
            get
            {
                return _Alpha;
            }
            set
            {
                _Alpha = value;
                RedrawImage();
            }
        }

        private bool _On = false;
        public bool On
        {
            get
            {
                return _On;
            }
            set
            {
                _On = value;

                RedrawImage();

                this.Invalidate();
            }
        }

        /// <summary>
        /// 单击后的图片
        /// </summary>
        public Image ClickedImage
        {
            get;
            set;
        }

        /// <summary>
        /// 未单击的图片
        /// </summary>
        public Image NoneClickedImage
        {
            get;
            set;
        }

        private int _OffsetX = 0;
        public int OffsetX
        {
            get
            {
                return _OffsetX;
            }
            set
            {
                _OffsetX = value;
                this.Invalidate();
            }
        }

        private int _OffsetY = 0;
        public int OffsetY
        {
            get
            {
                return _OffsetY;
            }
            set
            {
                _OffsetY = value;
                this.Invalidate();
            }
        }

        private int _BackGlowAlpha = 100;
        /// <summary>
        /// 背景光辉的透明度
        /// </summary>
        public int BackGlowAlpha
        {
            get
            {
                return _BackGlowAlpha;
            }
            set
            {
                _BackGlowAlpha = value;
                this.Invalidate();
            }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Click;
        protected override void OnClick(EventArgs e)
        {
            if (this.Click != null)
                Click(this, e);
        }

        public new event EventHandler StateChanged;
        protected void RaiseStateChanged()
        {
            if (this.StateChanged != null)
            {
                StateChanged(this, null);
            }
        }

        public LightText()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            this.Click += delegate
            {
                this.On = !this.On;
                RaiseStateChanged();
            };

            RedrawImage();
        }


        private Bitmap _DarkTextImage, _LightTextImage;

        private void RedrawImage()
        {
            ImageLightEffect(ref _LightTextImage, this.Text, this.Font, _LightColor, _GlowColor, _Alpha, _Blur);
            ImageLightEffect(ref _DarkTextImage, this.Text, this.Font, _DarkColor, _GlowColor, 0, _Blur);
        }

        private void ImageLightEffect(ref Bitmap textBitmap, string Str, Font F, Color ColorFore, Color ColorBack, int BackColorAlpha, int BlurConsideration)
        {
            textBitmap = null;//实例化Bitmap类
            using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))//实例化Graphics类
            {
                SizeF Var_Size = g.MeasureString(Str, F);//对字符串进行测量

                if (Var_Size.Width == 0 || Var_Size.Height == 0)
                    return;

                using (Bitmap Var_bmp = new Bitmap((int)Var_Size.Width, (int)Var_Size.Height))//通过文字的大小实例化Bitmap类
                using (Graphics Var_G_Bmp = Graphics.FromImage(Var_bmp))//实例化Bitmap类
                using (SolidBrush Var_BrushBack = new SolidBrush(Color.FromArgb(BackColorAlpha, ColorBack.R, ColorBack.G, ColorBack.B)))//根据RGB的值定义画刷
                using (SolidBrush Var_BrushFore = new SolidBrush(ColorFore))//定义画刷
                {
                    Var_G_Bmp.SmoothingMode = SmoothingMode.AntiAlias;//设置为高质量
                    Var_G_Bmp.InterpolationMode = InterpolationMode.HighQualityBilinear;//设置为高质量的收缩
                    Var_G_Bmp.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;//消除锯齿
                    Var_G_Bmp.DrawString(Str, F, Var_BrushBack, 0, 0);//绘制文字
                    textBitmap = new Bitmap(Var_bmp.Width + BlurConsideration, Var_bmp.Height + BlurConsideration);//根据辉光文字的大小实例化Bitmap类
                    using (Graphics Var_G_Bitmap = Graphics.FromImage(textBitmap))//实例化Graphics类
                    {
                        Var_G_Bitmap.SmoothingMode = SmoothingMode.AntiAlias;//设置为高质量
                        Var_G_Bitmap.InterpolationMode = InterpolationMode.HighQualityBilinear;//设置为高质量的收缩
                        Var_G_Bitmap.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;//消除锯齿


                        if (_On)
                        {
                            //遍历辉光文字的各象素点
                            for (int x = 0; x <= BlurConsideration; x++)
                            {
                                for (int y = 0; y <= BlurConsideration; y++)
                                {
                                    Var_G_Bitmap.DrawImageUnscaled(Var_bmp, x, y);//绘制辉光文字的点
                                }
                            }
                        }
                        Var_G_Bitmap.DrawString(Str, F, Var_BrushFore, BlurConsideration / 2, BlurConsideration / 2);//绘制文字
                    }
                }
            }
            this.Invalidate();
        }

        private GraphicsPath GetFilletRect(RectangleF r, float r1, float r2, float r3, float r4)
        {
            float x = r.X, y = r.Y, w = r.Width, h = r.Height;
            GraphicsPath rr = new GraphicsPath();
            rr.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y);
            rr.AddLine(x + r1, y, x + w - r2, y);
            rr.AddBezier(x + w - r2, y, x + w, y, x + w, y + r2, x + w, y + r2);
            rr.AddLine(x + w, y + r2, x + w, y + h - r3);
            rr.AddBezier(x + w, y + h - r3, x + w, y + h, x + w - r3, y + h, x + w - r3, y + h);
            rr.AddLine(x + w - r3, y + h, x + r4, y + h);
            rr.AddBezier(x + r4, y + h, x, y + h, x, y + h - r4, x, y + h - r4);
            rr.AddLine(x, y + h - r4, x, y + r1);
            return rr;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            if (_LightTextImage == null || _DarkTextImage == null)
                return;

            using (Bitmap bmp = new Bitmap(this.Width, this.Height))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;
                    g.Clear(Color.Transparent);

                    if (_On)
                    {

                        if (this.ClickedImage != null)
                        {
                            pe.Graphics.DrawImage(this.ClickedImage, new Rectangle(0, 0, this.Width, this.Height), new Rectangle(0, 0, this.ClickedImage.Width, this.ClickedImage.Height), GraphicsUnit.Pixel);
                        }
                        //Rectangle rec = new Rectangle(0, 0, _LightTextImage.Width, _LightTextImage.Height);
                        //                         //lb = new LinearGradientBrush(rec, Color.FromArgb(100, _GlowColor), Color.Transparent,LinearGradientMode.);
                        //                         //g.FillRectangle(lb, rec);
                        // 
                        //                         // 绘制圆角
                        //                         RectangleF rect = new RectangleF((this.Width - _LightTextImage.Width*1.7f) / 2f + _OffsetX, (this.Height - _LightTextImage.Height*1.2f) / 2f + _OffsetY, _LightTextImage.Width * 1.7f, _LightTextImage.Height * 1.2f);
                        //                         int radius = 50;
                        //                         System.Drawing.Drawing2D.GraphicsPath roundRect = new System.Drawing.Drawing2D.GraphicsPath();
                        //                         //顶端 
                        //                         roundRect.AddLine(rect.Left + radius - 1, rect.Top - 1, rect.Right - radius, rect.Top - 1);
                        //                         //右上角 
                        //                         roundRect.AddArc(rect.Right - radius, rect.Top - 1, radius, radius, 270, 90);
                        //                         //右边 
                        //                         roundRect.AddLine(rect.Right, rect.Top + radius, rect.Right, rect.Bottom - radius);
                        //                         //右下角
                        //                         roundRect.AddArc(rect.Right - radius, rect.Bottom - radius, radius, radius, 0, 90);
                        //                         //底边 
                        //                         roundRect.AddLine(rect.Right - radius, rect.Bottom, rect.Left + radius, rect.Bottom);
                        //                         //左下角 
                        //                         roundRect.AddArc(rect.Left - 1, rect.Bottom - radius, radius, radius, 90, 90);
                        //                         //左边 
                        //                         roundRect.AddLine(rect.Left - 1, rect.Top + radius, rect.Left - 1, rect.Bottom - radius);
                        //                         //左上角 
                        //                         roundRect.AddArc(rect.Left - 1, rect.Top - 1, radius, radius, 180, 90);


                        //PathGradientBrush pgb = new PathGradientBrush(roundRect);
                        RectangleF rect = new RectangleF((this.Width - _LightTextImage.Width * 1.5f) / 2f + _OffsetX, (this.Height - _LightTextImage.Height * 1.5f) / 2f + _OffsetY, _LightTextImage.Width * 1.5f, _LightTextImage.Height * 1.5f);
                        //GraphicsPath gp = GetFilletRect(rect, 5f, 5f, 5f, 5f);
                        GraphicsPath gp = new GraphicsPath();
                        gp.AddEllipse(new Rectangle(-20, -20, this.Width + 40, this.Height + 40));
                        PathGradientBrush pgb = new PathGradientBrush(gp);

                        //                         pgb.CenterColor = Color.FromArgb(100, _GlowColor);
                        //                         pgb.SurroundColors = new Color[] { Color.Transparent };
                        //                         pgb.
                        //                         g.FillPath(pgb, roundRect);
                        //                         pgb.Dispose();
                        //                         pgb = null;
                        //                         roundRect.Dispose();
                        //                         roundRect = null;


                        //从外到内渐变颜色
                        Color[] colors = 
                        { 
                           Color.Transparent,
                           Color.FromArgb(_BackGlowAlpha/10,_GlowColor),
                           Color.FromArgb(_BackGlowAlpha,_GlowColor)
                        };

                        //从内到外渐变位置百分比
                        float[] relativePositions = 
                        { 
                           0f, 
                           0.5f,
                           1f
                        };

                        ColorBlend colorBlend = new ColorBlend();
                        colorBlend.Colors = colors;
                        colorBlend.Positions = relativePositions;


                        pgb.InterpolationColors = colorBlend;

                        g.FillPath(pgb, gp);

                        g.DrawImage(_LightTextImage, (this.Width - _LightTextImage.Width) / 2 + _OffsetX, (this.Height - _LightTextImage.Height) / 2 + _OffsetY);
                    }
                    else
                    {
                        if (this.NoneClickedImage != null)
                        {
                            pe.Graphics.DrawImage(this.NoneClickedImage, new Rectangle(0, 0, this.Width, this.Height), new Rectangle(0, 0, this.NoneClickedImage.Width, this.NoneClickedImage.Height), GraphicsUnit.Pixel);
                        }

                        g.DrawImage(_DarkTextImage, (this.Width - _DarkTextImage.Width) / 2 + _OffsetX, (this.Height - _DarkTextImage.Height) / 2 + _OffsetY);
                    }
                }


                pe.Graphics.DrawImage(bmp, 0, 0);
            }

            base.OnPaint(pe);
        }
    }
}
